/*
* Copyright © Shanghai Awinic Technology Co., Ltd. 2020-2020. All rights reserved.
* Description: WDT driver related library function files.
* Date： 20201126
* Awinic_Version： aw_soc_driver_v1.0.0
*/
#include "compile_option.h"
#ifdef AW_86802

#include "aw8680x_global.h"

/**
  * @brief  WDT interrupt number configuration function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval RET_STATUS_E status
  */
static RET_STATUS_E wdt_irq_config(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Check the WDT handle allocation. */
	if (p_wdt_lib == AW_NULL) {
		return RET_ERROR;
	}

	NVIC_EnableIRQ(p_wdt_lib->wdt_irq_e); // Enable Interrupt.
	NVIC_SetPriority(p_wdt_lib->wdt_irq_e, p_wdt_lib->wdt_irq_pri_e); // Set Interrupt Priority.

	return RET_OK;
}

/**
  * @brief  WDT set time
  * @param  p_instance_s pointer to a WDT_TYPE_S structure that contains
  *             the register information for the specified WDT.
  * @param  AW_U8 set_time
  * @retval None
  */
RET_STATUS_E wdt_set_time(WDT_TYPE_S *p_instance_s, AW_U8 set_time)
{
	/* Check the WDT allocation. */
	if (p_instance_s == AW_NULL) {
		return RET_ERROR;
	}

	/* wdt_time = 2^(16+set_time)*(1/24M) */
	p_instance_s->RANGE = set_time; /* set_time is 0 to 15 */

	return RET_OK;
}

/**
  * @brief  WDT reset function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E wdt_reset(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Check the WDT handle allocation. */
	if (p_wdt_lib == AW_NULL) {
		return RET_ERROR;
	}

	p_wdt_lib->p_instance_s->RESTART = WDT_CRR_NUM;

	return RET_OK;
}

/**
  * @brief  WDT initialization function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E wdt_init(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Check the WDT handle allocation. */
	if (p_wdt_lib == AW_NULL) {
		return RET_ERROR;
	}

	assert_param(WDT_CHECK_INSTANCE(p_wdt_lib->p_instance_s));

	/* Config wdt. */
	if (p_wdt_lib->p_instance_s == WDT0) {
		wdt0_clk_init(); // Open wdt clk.
		wdt0_rst_en(); // Allow WDT auto reset.
	} else if (p_wdt_lib->p_instance_s == WDT1) {
		wdt1_clk_init(); // Open wdt clk.
		wdt1_rst_en(); // Allow WDT auto reset.
	}

	wdt_irq_config(p_wdt_lib); // Config wdt interrput number.
	wdt_set_time(p_wdt_lib->p_instance_s, p_wdt_lib->init_s.wdt_torr);
	wdt_reset(p_wdt_lib);
	p_wdt_lib->p_instance_s->CTRL = p_wdt_lib->init_s.wdt_mode_e | WDT_EN;

	return RET_OK;
}

/**
  * @brief  WDT clean interruption function.
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E wdt_clean_irq(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	__IO AW_U32 temp_flag = AW_NUM_NULL;

	/* Check the WDT handle allocation */
	if (p_wdt_lib == AW_NULL) {
		return RET_ERROR;
	}

	temp_flag = p_wdt_lib->p_instance_s->ICR;

	return RET_OK;
}

/**
  * @brief  WDT0 callback function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval None
  */
__weak void wdt0_irq_call(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Prevent unused argument(s) compilation warning */
	assert_param(p_wdt_lib);

	/* NOTE : This function Should not be modified, when the callback is needed,
			the aw_lib_wdt_call could be implemented in the user file
	*/

	/* Clear the existing interruption */
	wdt_clean_irq(p_wdt_lib);
}

/**
  * @brief  WDT1 callback function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval None
  */
__weak void wdt1_irq_call(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Prevent unused argument(s) compilation warning */
	assert_param(p_wdt_lib);

	/* NOTE : This function Should not be modified, when the callback is needed,
			the aw_lib_wdt_call could be implemented in the user file
	*/

	/* Clear the existing interruption */
	wdt_clean_irq(p_wdt_lib);
}

/**
  * @brief  WDT interruption of service function
  * @param  WDT pointer to a WDT_HANDLE_TYPE_S structure that contains
  *             the configuration information for the specified WDT.
  * @retval RET_STATUS_E status
  */
RET_STATUS_E wdt_irq(WDT_HANDLE_TYPE_S *p_wdt_lib)
{
	/* Check the WDT handle allocation. */
	if (p_wdt_lib == AW_NULL) {
		return RET_ERROR;
	}

	if (p_wdt_lib->p_instance_s == WDT0) {
		/* Add user's WDT service function. */
		wdt0_irq_call(p_wdt_lib);
	}

	if (p_wdt_lib->p_instance_s == WDT1) {
		/* Add user's WDT service function. */
		wdt1_irq_call(p_wdt_lib);
	}

	return RET_OK;
}
#endif
